// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-/* exported Keyboard */
+/* exported KeyboardManager */
const { Clutter, Gio, GLib, GObject, Meta, St } = imports.gi;
const Signals = imports.signals;
};
Signals.addSignalMethods(Keypad.prototype);
+var KeyboardManager = class KeyBoardManager {
+ constructor() {
+ this._keyboard = null;
+ this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
+ this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
+
+ this._lastDeviceId = null;
+ Meta.get_backend().connect('last-device-changed', (backend, deviceId) => {
+ let manager = Clutter.DeviceManager.get_default();
+ let device = manager.get_device(deviceId);
+
+ if (device.get_device_name().indexOf('XTEST') < 0) {
+ this._lastDeviceId = deviceId;
+ this._syncEnabled();
+ }
+ });
+ this._syncEnabled();
+ }
+
+ _lastDeviceIsTouchscreen() {
+ if (!this._lastDeviceId)
+ return false;
+
+ let manager = Clutter.DeviceManager.get_default();
+ let device = manager.get_device(this._lastDeviceId);
+
+ if (!device)
+ return false;
+
+ return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
+ }
+
+ _syncEnabled() {
+ let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
+ let enabled = enableKeyboard || this._lastDeviceIsTouchscreen();
+ if (!enabled && !this._keyboard)
+ return;
+
+ if (enabled && !this._keyboard) {
+ this._keyboard = new Keyboard();
+ } else if (!enabled && this._keyboard) {
+ this._keyboard.setCursorLocation(null);
+ Main.layoutManager.hideKeyboard(true);
+ this._keyboard.destroy();
+ this._keyboard = null;
+ }
+ }
+
+ get keyboardActor() {
+ return this._keyboard.actor;
+ }
+
+ get visible() {
+ return this._keyboard && this._keyboard.actor.visible;
+ }
+
+ open(monitor) {
+ if (this._keyboard)
+ this._keyboard.open(monitor);
+ }
+
+ close() {
+ if (this._keyboard)
+ this._keyboard.close();
+ }
+
+ addSuggestion(text, callback) {
+ if (this._keyboard)
+ this._keyboard.addSuggestion(text, callback);
+ }
+
+ resetSuggestions() {
+ if (this._keyboard)
+ this._keyboard.resetSuggestions();
+ }
+
+ shouldTakeEvent(event) {
+ if (!this._keyboard)
+ return false;
+
+ let actor = event.get_source();
+ return Main.layoutManager.keyboardBox.contains(actor) ||
+ !!actor._extended_keys || !!actor.extended_key;
+ }
+};
+
var Keyboard = class Keyboard {
constructor() {
- this.actor = null;
+ this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true });
this._focusInExtendedKeys = false;
this._emojiActive = false;
this._animFocusedWindow = null;
this._delayedAnimFocusWindow = null;
- this._enableKeyboard = false; // a11y settings value
- this._enabled = false; // enabled state (by setting or device type)
this._latched = false; // current level is latched
- this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
- this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
- this._lastDeviceId = null;
this._suggestions = null;
this._emojiKeyVisible = Meta.is_wayland_compositor();
this._focusTracker = new FocusTracker();
- this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
- this._focusTracker.connect('reset', () => {
+ this._connectSignal(this._focusTracker, 'position-changed',
+ this._onFocusPositionChanged.bind(this));
+ this._connectSignal(this._focusTracker, 'reset', () => {
this._delayedAnimFocusWindow = null;
this._animFocusedWindow = null;
this._oskFocusWindow = null;
});
- this._focusTracker.connect('focus-changed', (tracker, focused) => {
- // Valid only for X11
- if (Meta.is_wayland_compositor())
- return;
-
- if (focused)
- this.open(Main.layoutManager.focusIndex);
- else
- this.close();
- });
-
- Meta.get_backend().connect('last-device-changed',
- (backend, deviceId) => {
- let manager = Clutter.DeviceManager.get_default();
- let device = manager.get_device(deviceId);
-
- if (!device.get_device_name().includes('XTEST')) {
- this._lastDeviceId = deviceId;
- this._syncEnabled();
- }
+ // Valid only for X11
+ if (!Meta.is_wayland_compositor()) {
+ this._connectSignal(this._focusTracker, 'focus-changed', (_tracker, focused) => {
+ if (focused)
+ this.open(Main.layoutManager.focusIndex);
+ else
+ this.close();
});
- this._syncEnabled();
+ }
this._showIdleId = 0;
this._keyboardVisible = false;
- Main.layoutManager.connect('keyboard-visible-changed', (o, visible) => {
+ this._connectSignal(Main.layoutManager, 'keyboard-visible-changed', (_lm, visible) => {
this._keyboardVisible = visible;
});
this._keyboardRequested = false;
this._keyboardRestingId = 0;
- Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
- }
+ this._connectSignal(Main.layoutManager, 'monitors-changed', this._relayout.bind(this));
- get visible() {
- return this._keyboardVisible;
+ this._setupKeyboard();
+
+ this.actor.connect('destroy', this._onDestroy.bind(this));
}
- _onFocusPositionChanged(focusTracker) {
- let rect = focusTracker.getCurrentRect();
- this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
+ destroy() {
+ this.actor.destroy();
}
- _lastDeviceIsTouchscreen() {
- if (!this._lastDeviceId)
- return false;
+ _connectSignal(obj, signal, callback) {
+ if (!this._connectionsIDs)
+ this._connectionsIDs = [];
- let manager = Clutter.DeviceManager.get_default();
- let device = manager.get_device(this._lastDeviceId);
+ let id = obj.connect(signal, callback);
+ this._connectionsIDs.push([obj, id]);
+ return id;
+ }
- if (!device)
- return false;
+ get visible() {
+ return this._keyboardVisible && this.actor.visible;
+ }
- return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
+ _onFocusPositionChanged(focusTracker) {
+ let rect = focusTracker.getCurrentRect();
+ this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
}
- _syncEnabled() {
- let wasEnabled = this._enabled;
- this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
- this._enabled = this._enableKeyboard || this._lastDeviceIsTouchscreen();
- if (!this._enabled && !this._keyboardController)
- return;
+ _onDestroy() {
+ for (let [obj, id] of this._connectionsIDs)
+ obj.disconnect(id);
+ delete this._connectionsIDs;
- if (this._enabled && !this._keyboardController)
- this._setupKeyboard();
- else if (!this._enabled)
- this.setCursorLocation(null);
+ this._clearShowIdle();
- if (!this._enabled && wasEnabled)
- Main.layoutManager.hideKeyboard(true);
- }
+ this._keyboardController = null;
+ this._suggestions = null;
+ this._aspectContainer = null;
+ this._emojiSelection = null;
+ this._keypad = null;
- _destroyKeyboard() {
- if (this._keyboardNotifyId)
- this._keyboardController.disconnect(this._keyboardNotifyId);
- if (this._keyboardGroupsChangedId)
- this._keyboardController.disconnect(this._keyboardGroupsChangedId);
- if (this._keyboardStateId)
- this._keyboardController.disconnect(this._keyboardStateId);
- if (this._emojiKeyVisibleId)
- this._keyboardController.disconnect(this._emojiKeyVisibleId);
- if (this._keypadVisibleId)
- this._keyboardController.disconnect(this._keypadVisibleId);
- if (this._focusNotifyId)
- global.stage.disconnect(this._focusNotifyId);
- this._clearShowIdle();
- this._keyboard = null;
- this.actor.destroy();
- this.actor = null;
+ Main.layoutManager.untrackChrome(this.actor);
+ Main.layoutManager.keyboardBox.remove_actor(this.actor);
if (this._languagePopup) {
this._languagePopup.destroy();
}
_setupKeyboard() {
- this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
Main.layoutManager.keyboardBox.add_actor(this.actor);
Main.layoutManager.trackChrome(this.actor);
this._emojiSelection.actor.hide();
this._keypad = new Keypad();
- this._keypad.connect('keyval', (keypad, keyval) => {
+ this._connectSignal(this._keypad, 'keyval', (_keypad, keyval) => {
this._keyboardController.keyvalPress(keyval);
this._keyboardController.keyvalRelease(keyval);
});
// keyboard on RTL locales.
this.actor.text_direction = Clutter.TextDirection.LTR;
- this._keyboardNotifyId = this._keyboardController.connect('active-group', this._onGroupChanged.bind(this));
- this._keyboardGroupsChangedId = this._keyboardController.connect('groups-changed', this._onKeyboardGroupsChanged.bind(this));
- this._keyboardStateId = this._keyboardController.connect('panel-state', this._onKeyboardStateChanged.bind(this));
- this._keypadVisibleId = this._keyboardController.connect('keypad-visible', this._onKeypadVisible.bind(this));
- this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
+ this._connectSignal(this._keyboardController, 'active-group',
+ this._onGroupChanged.bind(this));
+ this._connectSignal(this._keyboardController, 'groups-changed',
+ this._onKeyboardGroupsChanged.bind(this));
+ this._connectSignal(this._keyboardController, 'panel-state',
+ this._onKeyboardStateChanged.bind(this));
+ this._connectSignal(this._keyboardController, 'keypad-visible',
+ this._onKeypadVisible.bind(this));
+ this._connectSignal(global.stage, 'notify::key-focus',
+ this._onKeyFocusChanged.bind(this));
if (Meta.is_wayland_compositor())
- this._emojiKeyVisibleId = this._keyboardController.connect('emoji-visible', this._onEmojiKeyVisible.bind(this));
+ this._connectSignal(this._keyboardController, 'emoji-visible',
+ this._onEmojiKeyVisible.bind(this));
this._relayout();
}
this._showIdleId = 0;
return GLib.SOURCE_REMOVE;
});
- GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
+ GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.open');
}
}
this._updateCurrentPageVisible();
}
- shouldTakeEvent(event) {
- let actor = event.get_source();
- return Main.layoutManager.keyboardBox.contains(actor) ||
- !!actor._extended_keys || !!actor.extended_key;
- }
-
_clearKeyboardRestTimer() {
if (!this._keyboardRestingId)
return;
}
open(monitor) {
- if (!this._enabled)
- return;
-
this._clearShowIdle();
this._keyboardRequested = true;
}
close() {
- if (!this._enabled)
- return;
-
this._clearShowIdle();
this._keyboardRequested = false;